#include "account.h"
#include "game.h"
#include "globals.h"
#include "config.h"
#include "graphics.h"
#include "network.h"
#include "packetstream.h"
#include "connect.h"
#include "characters.h"

// Initializes the state
bool AccountState::Show() 
{
	int DrawX = 400, DrawY = 250, ButtonWidth = 80;
	Form = irrGUI->addTab(GraphicsClass::Instance().GetRect(0, 0, 800, 600));

	if(AccountName == "")
		AccountName = ConfigClass::Instance().GetLastAccountName();

	// Account
	GraphicsClass::Instance().SetFont(GraphicsClass::FONT_10);
	TextAccountName = GraphicsClass::Instance().AddText("Account", DrawX, DrawY, GraphicsClass::ALIGN_CENTER, Form);

	DrawY += 35;
	EditAccountName = irrGUI->addEditBox(L"", GraphicsClass::Instance().GetCenteredRect(DrawX, DrawY, 180, 25), true, Form, ELEMENT_ACCOUNT);
	EditAccountName->setMax(15);
	EditAccountName->setText(stringw(AccountName.c_str()).c_str());

	// Password
	DrawY += 35;
	TextPassword = GraphicsClass::Instance().AddText("Password", DrawX, DrawY, GraphicsClass::ALIGN_CENTER, Form);

	DrawY += 35;
	EditPassword = irrGUI->addEditBox(L"", GraphicsClass::Instance().GetCenteredRect(DrawX, DrawY, 180, 25), true, Form, ELEMENT_PASSWORD);
	EditPassword->setPasswordBox(true);
	EditPassword->setMax(15);
	EditPassword->setText(stringw(Password.c_str()).c_str());

	// Buttons
	DrawY += 50;
	ButtonLogin = irrGUI->addButton(GraphicsClass::Instance().GetCenteredRect(DrawX - 50, DrawY, ButtonWidth, 25), Form, ELEMENT_LOGIN, L"Log in");
	ButtonCancel = irrGUI->addButton(GraphicsClass::Instance().GetCenteredRect(DrawX + 50, DrawY, ButtonWidth, 25), Form, ELEMENT_CANCEL, L"Cancel");

	// Create account
	DrawY += 50;
	ButtonCreateAccount = irrGUI->addButton(GraphicsClass::Instance().GetCenteredRect(DrawX, DrawY, 120, 25), Form, ELEMENT_CREATEACCOUNT, L"Create Account");

	Message = "";
	ChangeState(STATE_MAIN);

	return true;
}

// Shuts the state down
bool AccountState::Hide() 
{
	return true;
}

// Handles a disconnection from the server
void AccountState::HandleDisconnect(ENetEvent *TEvent) 
{
	CGame::Instance().SwitchState("GS_CONNECT");
}

// Handles a server packet
void AccountState::HandlePacket(ENetEvent *TEvent) 
{
	PacketClass Packet(TEvent->packet);
	switch(Packet.ReadChar()) 
	{
		case NetworkClass::ACCOUNT_NOTFOUND:
			Message = "Account not found";
			ChangeState(STATE_MAIN);
		break;
		case NetworkClass::ACCOUNT_EXISTS:
			Message = "Account exists";
			ChangeState(STATE_MAIN);
		break;
		case NetworkClass::ACCOUNT_ALREADYLOGGEDIN:
			Message = "Account is already logged into";
			ChangeState(STATE_MAIN);
		break;
		case NetworkClass::ACCOUNT_SUCCESS:
			ConfigClass::Instance().SetLastAccountName(AccountName);
			ConfigClass::Instance().SaveSettings();
			AccountName = "";
			Password = "";
			CGame::Instance().SwitchState("GS_CHARACTER");
		break;
	}
}

// Updates the current state
void AccountState::Update(u32 TDeltaTime) 
{

}

// Draws the current state
void AccountState::Draw() 
{
	GraphicsClass::Instance().DrawImage(GraphicsClass::IMAGE_MENULOGO, 400, 125);

	// Server message
	if(Message.size() > 0) {
		GraphicsClass::Instance().SetFont(GraphicsClass::FONT_10);
		GraphicsClass::Instance().RenderText(Message.c_str(), 400, 200, GraphicsClass::ALIGN_CENTER, SColor(255, 255, 0, 0));
	}

	switch(State) {
		case STATE_MAIN:
		break;
		case STATE_LOGIN:
			GraphicsClass::Instance().SetFont(GraphicsClass::FONT_10);
			GraphicsClass::Instance().RenderText("Sending information...", 400, 250, GraphicsClass::ALIGN_CENTER);
		break;
	}

	irrGUI->drawAll();
}

// Key presses
bool AccountState::HandleKeyPress(EKEY_CODE TKey) 
{
	switch(State) 
	{
		case STATE_MAIN:
			switch(TKey) 
			{
				case KEY_ESCAPE:
					CGame::Instance().SwitchState("GS_CONNECT");
				break;
				case KEY_RETURN:
					ChangeState(STATE_LOGIN);
				break;
			}				
		break;
	}
	
	return false;
}

// GUI events
void AccountState::HandleGUI(EGUI_EVENT_TYPE TEventType, IGUIElement *TElement) 
{
	switch(State) 
	{
		case STATE_MAIN:
			switch(TEventType) 
			{
				case EGET_BUTTON_CLICKED:
					switch(TElement->getID()) 
					{
						case ELEMENT_LOGIN:
							CreateAccount = false;
							ChangeState(STATE_LOGIN);
						break;
						case ELEMENT_CANCEL:
							CGame::Instance().SwitchState("GS_CONNECT");
						break;
						case ELEMENT_CREATEACCOUNT:
							CreateAccount = true;
							ChangeState(STATE_LOGIN);
						break;
					}
				break;
			}
		break;
	}
}

// Changes the internal state
void AccountState::ChangeState(int TState) 
{
	switch(TState) 
	{
		case STATE_MAIN:
			Form->setVisible(true);
			CreateAccount = false;
			if(AccountName == "")
				irrGUI->setFocus(EditAccountName);
			else
				irrGUI->setFocus(EditPassword);

			State = TState;
		break;
		case STATE_LOGIN:
			if(ValidateForm()) 
			{
				Form->setVisible(false);
				Message = "";
				State = TState;

				// Send information
				PacketClass Packet(NetworkClass::ACCOUNT_LOGININFO);
				Packet.WriteBit(CreateAccount);
				Packet.WriteString(AccountName.c_str());
				Packet.WriteString(Password.c_str());
				CGame::Instance().SendPacketToHost(&Packet);
			}
		break;
	}	
}

// Validates the login form
bool AccountState::ValidateForm() 
{
	AccountName = EditAccountName->getText();
	AccountName.trim();

	Password = EditPassword->getText();
	Password.trim();

	if(AccountName.size() == 0) 
	{
		Message = "Invalid account name";
		irrGUI->setFocus(EditAccountName);
		return false;
	}
	else 
	if(Password.size() == 0) 
	{
		Message = "Invalid password";
		irrGUI->setFocus(EditPassword);
		return false;
	}

	return true;
}

// Sets the default login info
void AccountState::SetLoginInfo(const stringc &TAccountName, const stringc &TPassword) 
{
	AccountName = TAccountName;
	Password = TPassword;
}
